Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw informative errors when backends are not loaded #214

Merged
merged 4 commits into from
Apr 25, 2024
Merged

Conversation

adrhill
Copy link
Collaborator

@adrhill adrhill commented Apr 25, 2024

When forgetting to load a backend package, most operators error at either prepare_pullback_aux or prepare_pushforward_aux, resulting in an uninformative MethodError:

julia> gradient(f, backend, x)
ERROR: MethodError: no method matching prepare_pushforward_aux(::typeof(f), ::AutoForwardDiff{…}, ::Vector{…}, ::FillArrays.OneElement{…}, ::DifferentiationInterface.PushforwardFast)

This PR adds these missing methods, throwing an informative error that suggests loading the respective backend.

New errors

julia> gradient(f, AutoEnzyme(), x)
ERROR: Failed to prepare pullback for Enzyme (forward/reverse) backend. 
This usually due to the backend not being loaded. To fix, specify

    using Enzyme

Stacktrace:
 [1] prepare_pullback_aux(f::Function, backend::AutoEnzyme{Nothing}, x::Vector{Float64}, dy::Float64, ::DifferentiationInterface.PullbackFast)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:98
 [2] prepare_pullback(f::Function, backend::AutoEnzyme{Nothing}, x::Vector{Float64}, dy::Float64)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:68
 [3] prepare_gradient(f::typeof(f), backend::AutoEnzyme{Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:48
 [4] gradient(f::Function, backend::AutoEnzyme{Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:73
 [5] top-level scope
   @ REPL[21]:1
julia> gradient(f, AutoForwardDiff(), x)
ERROR: Failed to prepare pushforward for ForwardDiff (forward) backend. 
This usually due to the backend not being loaded. To fix, specify

    using ForwardDiff

Stacktrace:
 [1] prepare_pushforward_aux(f::Function, backend::AutoForwardDiff{…}, x::Vector{…}, dy::FillArrays.OneElement{…}, ::DifferentiationInterface.PushforwardFast)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:87
 [2] prepare_pushforward(f::Function, backend::AutoForwardDiff{…}, x::Vector{…}, dx::FillArrays.OneElement{…})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:56
 [3] prepare_pullback_aux(f::Function, backend::AutoForwardDiff{…}, x::Vector{…}, dy::Float64, ::DifferentiationInterface.PullbackSlow)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:77
 [4] prepare_pullback(f::Function, backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64}, dy::Float64)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:68
 [5] prepare_gradient(f::typeof(f), backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:48
 [6] gradient(f::Function, backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:73
 [7] top-level scope
   @ REPL[24]:1
Some type information was truncated. Use `show(err)` to see complete types.

Previous errors

julia> gradient(f, backend, x)
ERROR: MethodError: no method matching prepare_pushforward_aux(::typeof(f), ::AutoForwardDiff{…}, ::Vector{…}, ::FillArrays.OneElement{…}, ::DifferentiationInterface.PushforwardFast)

Closest candidates are:
  prepare_pushforward_aux(::Any, ::Any, ::Any, ::Any, ::Any, ::DifferentiationInterface.PushforwardSlow)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:70
  prepare_pushforward_aux(::Any, ::Any, ::Any, ::Any, ::DifferentiationInterface.PushforwardSlow)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:63

Stacktrace:
 [1] prepare_pushforward(f::Function, backend::AutoForwardDiff{…}, x::Vector{…}, dx::FillArrays.OneElement{…})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:56
 [2] prepare_pullback_aux(f::Function, backend::AutoForwardDiff{…}, x::Vector{…}, dy::Float64, ::DifferentiationInterface.PullbackSlow)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:77
 [3] prepare_pullback(f::Function, backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64}, dy::Float64)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:68
 [4] prepare_gradient(f::typeof(f), backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:48
 [5] gradient(f::Function, backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:73
 [6] top-level scope
   @ REPL[8]:1
Some type information was truncated. Use `show(err)` to see complete types.

@codecov-commenter
Copy link

codecov-commenter commented Apr 25, 2024

Codecov Report

Attention: Patch coverage is 64.00000% with 9 lines in your changes are missing coverage. Please review.

Project coverage is 95.85%. Comparing base (e549302) to head (07709ea).
Report is 4 commits behind head on main.

Files Patch % Lines
DifferentiationInterface/src/utils/exceptions.jl 16.66% 5 Missing ⚠️
DifferentiationInterface/src/utils/printing.jl 86.66% 2 Missing ⚠️
...fferentiationInterface/src/first_order/pullback.jl 50.00% 1 Missing ⚠️
...rentiationInterface/src/first_order/pushforward.jl 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #214      +/-   ##
==========================================
- Coverage   96.40%   95.85%   -0.55%     
==========================================
  Files          65       70       +5     
  Lines        3558     3791     +233     
==========================================
+ Hits         3430     3634     +204     
- Misses        128      157      +29     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@gdalle
Copy link
Member

gdalle commented Apr 25, 2024

Can we check that these exceptions are indeed thrown? i.e. by defining a fake backend with no operators

@gdalle
Copy link
Member

gdalle commented Apr 25, 2024

You can use 'check_available' before throwing the exception to confirm the "unloaded" diagnosis. Otherwise the user should probably open an issue, cause I can't think of any other situation where we hit that missing method on purpose

@adrhill
Copy link
Collaborator Author

adrhill commented Apr 25, 2024

Update with MissingBackendError and using check_available before printing the suggestion to load the backend package:

julia> gradient(f, AutoEnzyme(), x)
ERROR: failed to use Enzyme (forward/reverse) backend.
Backend package is not loaded. To fix, run

  using Enzyme

Stacktrace:
 [1] prepare_pullback_aux(f::Function, backend::AutoEnzyme{Nothing}, x::Vector{Float64}, dy::Float64, ::DifferentiationInterface.PullbackFast)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:88
 [2] prepare_pullback(f::Function, backend::AutoEnzyme{Nothing}, x::Vector{Float64}, dy::Float64)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:68
 [3] prepare_gradient(f::typeof(f), backend::AutoEnzyme{Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:48
 [4] gradient(f::Function, backend::AutoEnzyme{Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:73
 [5] top-level scope
   @ REPL[13]:1

julia> gradient(f, AutoBrokenReverse(), x)
ERROR: failed to use AutoBrokenReverse (reverse) backend.
Please open an issue: https://github.com/gdalle/DifferentiationInterface.jl/issues/new
Stacktrace:
 [1] prepare_pullback_aux(f::Function, backend::AutoBrokenReverse, x::Vector{Float64}, dy::Float64, ::DifferentiationInterface.PullbackFast)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:88
 [2] prepare_pullback(f::Function, backend::AutoBrokenReverse, x::Vector{Float64}, dy::Float64)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:68
 [3] prepare_gradient(f::typeof(f), backend::AutoBrokenReverse, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:48
 [4] gradient(f::Function, backend::AutoBrokenReverse, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:73
 [5] top-level scope
   @ REPL[14]:1

julia> gradient(f, AutoForwardDiff(), x)
ERROR: failed to use ForwardDiff (forward) backend.
Backend package is not loaded. To fix, run

  using ForwardDiff

Stacktrace:
 [1] prepare_pushforward_aux(f::Function, backend::AutoForwardDiff{…}, x::Vector{…}, dy::FillArrays.OneElement{…}, ::DifferentiationInterface.PushforwardFast)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:77
 [2] prepare_pushforward(f::Function, backend::AutoForwardDiff{…}, x::Vector{…}, dx::FillArrays.OneElement{…})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:56
 [3] prepare_pullback_aux(f::Function, backend::AutoForwardDiff{…}, x::Vector{…}, dy::Float64, ::DifferentiationInterface.PullbackSlow)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:77
 [4] prepare_pullback(f::Function, backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64}, dy::Float64)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:68
 [5] prepare_gradient(f::typeof(f), backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:48
 [6] gradient(f::Function, backend::AutoForwardDiff{nothing, Nothing}, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:73
 [7] top-level scope
   @ REPL[15]:1
Some type information was truncated. Use `show(err)` to see complete types.

julia> gradient(f, AutoBrokenForward(), x)
ERROR: failed to use AutoBrokenForward (forward) backend.
Please open an issue: https://github.com/gdalle/DifferentiationInterface.jl/issues/new
Stacktrace:
 [1] prepare_pushforward_aux(f::Function, backend::AutoBrokenForward, x::Vector{…}, dy::FillArrays.OneElement{…}, ::DifferentiationInterface.PushforwardFast)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:77
 [2] prepare_pushforward(f::Function, backend::AutoBrokenForward, x::Vector{Float64}, dx::FillArrays.OneElement{Float64, 1, Tuple{…}, Tuple{…}})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pushforward.jl:56
 [3] prepare_pullback_aux(f::Function, backend::AutoBrokenForward, x::Vector{Float64}, dy::Float64, ::DifferentiationInterface.PullbackSlow)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:77
 [4] prepare_pullback(f::Function, backend::AutoBrokenForward, x::Vector{Float64}, dy::Float64)
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/pullback.jl:68
 [5] prepare_gradient(f::typeof(f), backend::AutoBrokenForward, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:48
 [6] gradient(f::Function, backend::AutoBrokenForward, x::Vector{Float64})
   @ DifferentiationInterface ~/Developer/DifferentiationInterface.jl/DifferentiationInterface/src/first_order/gradient.jl:73
 [7] top-level scope
   @ REPL[16]:1
Some type information was truncated. Use `show(err)` to see complete types.

@adrhill adrhill requested a review from gdalle April 25, 2024 16:54
@gdalle gdalle merged commit 32b70a2 into main Apr 25, 2024
5 checks passed
@gdalle gdalle deleted the ah/load-error branch April 25, 2024 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants